package de.breitbeil.samsyncro.lib;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;

import de.breitbeil.samsyncro.lib.connection.MObexConnection;
import de.breitbeil.samsyncro.lib.domain.pim.SVCard;
import de.breitbeil.samsyncro.lib.util.BTUtil;
import de.breitbeil.samsyncro.lib.util.Util;

public class Application {

    public static void main(String[] args) throws Exception {
        Application app = new Application(args);
        try {
            app.process();
        }
        catch(Exception e) {
            throw e;
        }
        finally {
            app.close();
        }
    }
    
    private String[] args;
    private MObexConnection connection;
    private PrintStream out;
    
    public Application(String[] args) {
        this(args, System.out);
    }
    
    public Application(String[] args, PrintStream out) {
        this.args = args;
        this.out = out;
    }
    
    public void close() throws IOException {
        if(connection != null) {
            connection.closeConnection();
        }
    }
    
    public void process() throws IOException {
        if(args.length == 0 || isCommandSet("--help")) {
            printHelp();
        }
        if(isCommandSet("--scan")) {
            BTUtil.scan();
        }
        if(isCommandSet("--version")) {
            out.println(Util.getVersion());
            out.println(Util.getBuild());
        }
        if(isCommandSet("--address")) {
            connect();
        }
        if(isCommandSet("--clist")) {
            ensureConnection();
            clist();
        }
        if(isCommandSet("--cdelete")) {
            ensureConnection();
            cdelete();
        }
        if(isCommandSet("--cbackup")) {
            ensureConnection();
            cbackup();
        }
        if(isCommandSet("--cupdate")) {
            ensureConnection();
            cupdate();
        }
        if(isCommandSet("--ccreate")) {
            ensureConnection();
            ccreate();
        }
    }
    
    public void connect() {
        String arg = getCommandArgument("--address");
        String adress[] = arg.split(":");
        if(adress.length != 2) {
            out.println("Error: Cannot parse adress. The adress must be of format <bluetooth address>:<channel> but was "+arg);
            System.exit(-1);
        }
        else {
            connection = new MObexConnection();
            connection.openConnection(adress[0], Integer.parseInt(adress[1]));
        }
    }
    
    public void ensureConnection() {
        if(connection == null) {
            out.println("Error: Address not set. Use --address to specify the device to connect to.");
            System.exit(-1);
        }
    }
    
    // Contact methods
    
    public void clist() throws IOException {
        List<SVCard> cards = connection.getContacts();
        for(SVCard card: cards) {
            out.println(card);
        }
    }
    
    public void cdelete() throws NumberFormatException, IOException {
        String id = getCommandArgument("--cdelete");
        connection.deleteContact(Integer.parseInt(id));
    }
    
    public void ccreate() throws IOException {
        List<SVCard> list = Util.getvCards(new File(args[2]));
        for(SVCard card: list) {
            try {
                out.print("Creating contact...");
                connection.createContact(card);
                out.println(" success.");
            }
            catch(Exception e) {
                out.println(" failed. Card: "+card);
                e.printStackTrace();
            }
            
        }
    }
    
    public void cupdate() throws IOException {
        String arg = getCommandArgument("--cupdate");
        List<SVCard> list = Util.getvCards(new File(arg));
        for(SVCard card: list) {
            try {
                out.print("Updating id "+card.getId()+"...");
                connection.updateContact(card);
                out.println(" success.");
            }
            catch(Exception e) {
                out.println(" failed.");
                e.printStackTrace();
            }
        }
    }
    
    public void cbackup() throws IOException {
        String arg = getCommandArgument("--cbackup");
        File file = new File(arg);

        if(!file.exists() && !file.createNewFile()) {
             out.println("Can't create file "+args[2]);
             System.exit(-1);
        }
        
        FileWriter writer = new FileWriter(file);
        List<SVCard> cards = connection.getContacts();
        for(SVCard card: cards) {
            writer.write(card.toString()+"\r\n");
        }
        writer.close();
    }
    
    
    // Access to commandline Arguments
    
    public boolean isCommandSet(String cmd) {
        return getCommandPosition(cmd) >= 0;
    }
    
    public int getCommandPosition(String cmd) {
        for(int i = 0; i < args.length; i++) {
            if(args[i].equals(cmd)) {
                return i;
            }
        }
        return -1;
    }
    
    public String getCommandArgument(String cmd) {
        int posCmd = getCommandPosition(cmd);
        int posArg = posCmd + 1;
        
        if(posCmd < 0) {
            throw new RuntimeException("Command not specified: "+cmd); 
        }
        
        if(posArg >= args.length || args[posArg].startsWith("--")) {
            throw new RuntimeException("Argument for command "+cmd+" not specified.");
        }
        
        return args[posArg];
    }
    
    // Help

    public void printHelp() {
        out.println("Usage: java -jar libsamsync.jar <command> <adress>");
        out.println("");
        out.println("Possible commands are");
        out.println("  --help             prints this help");
        out.println("  --version          prints the version");
        out.println();
        out.println("  --scan             lists all accessable bluetooth devices");
        out.println();
        out.println("  --clist            lists all contacts");
        out.println("  --cdelete <id>     deletes a contact. Parameter 1: Id of the contact.");
        out.println("  --cbackup <file>   stores all contacts in a single file. Parameter 1: the backup file.");
        out.println("  --cupdate <file>   reads a file and updates all contacts on the mobile. Attention: the contacts on the mobile will be overridden. Parameter 1: the backup file.");
        out.println("  --ccreate <file>   reads a file and creates all contacts on the mobile. Parameter 1: the backup file.");
        out.println();
        out.println("The bluetooth address must be set with");
        out.println("  --address <bluetooth adress>:<channel>    For example --address 444E1A192BCE:3. The channel must be set to the serial channel of your mobile. ");
        out.println();
        out.println("If you need more debug information, a log file is created in your temp dir called samsync.log");
        out.println();
    }
    
}
